package com.demo.webapp.kcfinder.interceptor;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.demo.webapp.kcfinder.ActionMapping;
import com.demo.webapp.kcfinder.ActionProxy;
import com.demo.webapp.kcfinder.action.Action;
import com.demo.webapp.kcfinder.action.UploadFileItemAware;
import com.demo.webapp.kcfinder.context.ActionContext;

/**
 * 文件上传
 * @author ryuu.kk
 *
 */
public class KCFinderUploadInterceptor implements Interceptor {

	//文件最大50M
	protected static final int FILE_SIZE_MAX = 50*1024*1024;
		
	//单文件内存最大使用4M
	protected static final int MEM_SIZE_MAX = 4*1024;
	
	/**
	 * 最大文件限制
	 */
	private int maxFileSize = FILE_SIZE_MAX;
	
	/**
	 * 最大内存使用量(单个上传文件)
	 */
	private int maxMemSize = MEM_SIZE_MAX;
	
	/**
	 * 临时文件位置 
	 */
	private String tmpPath = "/data";
	
	@SuppressWarnings("unchecked")
	@Override
	public String intercept(ActionProxy proxy, ActionMapping mapping) throws Exception {
		
		//得到Action
		Action action = proxy.getAction();
		ActionContext context = ActionContext.getContext();
		HttpServletRequest request = context.getRequest();
		
		String encoding = context.getEncoding();
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);

		if( !isMultipart ){
			//非二进制文件上传,中止执行,跳转到错误页
			//加入错误提示信息
			return Interceptor.ACTION_EXECUTE_ABORT;
		}
		
		DiskFileItemFactory factory = new DiskFileItemFactory();
		
		// 将要存储在内存的最大值
		factory.setSizeThreshold(maxMemSize);
		
		// 存储在本地的最大空间分配(相比内存将分配更大空间)
		tmpPath = context.getServletContext().getRealPath(tmpPath);
		if (!tmpPath.startsWith("/")) {
			tmpPath = "/" + tmpPath;
		};
		File tmpFile = new File(tmpPath);
		if (!tmpFile.exists()) {
			tmpFile.mkdirs();
		}
		
		factory.setRepository(tmpFile);
		
		// 创建一个上传的新文件句柄
		ServletFileUpload upload = new ServletFileUpload(factory);
		
		// 上传文件的最大值
		upload.setSizeMax(maxFileSize);
		
		List<FileItem> fileItems;
		List<FileItem> newfileDataItems;
		try {
			// 分解request，得到文件items.
			fileItems = upload.parseRequest(request);
			// 新文件内容List(只包含上传文件数据,排除参数信息)
			newfileDataItems = new ArrayList<FileItem>(fileItems.size());
			
			//  遍历上传的文件(包括一起Post的参数)
			Iterator<FileItem> i = fileItems.iterator();

			while(i.hasNext()) {
				FileItem item = i.next();
				// 是上传参数，分解参数注入到Action中
				if (item.isFormField()) {
					//~~ 取得上传文件参数 =====================================================================
					String paramKey = item.getFieldName();
					String paramValue = item.getString(encoding);
					
					request.setAttribute(paramKey, paramValue);
					
				} else {
					newfileDataItems.add(item);
				}
			}
			
			if (UploadFileItemAware.class.isAssignableFrom(action.getClass())) {
				((UploadFileItemAware)action).setFileItems(newfileDataItems);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			//out.flush();
			//out.close();
		}
		return null;
	}

	//~~ 基础参数设置 -----------------------------------
	public void setMaxFileSize(int maxFileSize) {
		this.maxFileSize = maxFileSize;
	}

	public void setMaxMemSize(int maxMemSize) {
		this.maxMemSize = maxMemSize;
	}

	public void setTmpPath(String tmpPath) {
		this.tmpPath = tmpPath;
	}
}
